#include "stringwheelwidget.h"
#include <QPainter>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QDebug>
#include <cmath>

StringWheelWidget::StringWheelWidget(QWidget *parent)
    : QWidget(parent),
    m_orientation(Qt::Vertical),
    m_itemSize(40),
    m_visibleItemCount(5), // 默认显示5个
    m_currentPosition(0.0),
    m_isDragging(false),
    m_lastMousePos(0)
{
    // 1. 强制铺满父窗口 (如果父窗口存在)
    if (parent) {
        this->resize(parent->size());
    } else {
        this->resize(200, 300);
    }

    // 初始化吸附动画
    m_snapAnimation = new QPropertyAnimation(this, "currentPosition", this);
    m_snapAnimation->setDuration(300);
    m_snapAnimation->setEasingCurve(QEasingCurve::OutQuad);

    // 根据当前尺寸计算一下行高
    recalcItemSize();
}

void StringWheelWidget::setItems(const QStringList &items)
{
    m_items = items;
    m_currentPosition = 0.0;
    update();
}

QStringList StringWheelWidget::items() const
{
    return m_items;
}

int StringWheelWidget::currentIndex() const
{
    return static_cast<int>(std::round(m_currentPosition));
}

void StringWheelWidget::setCurrentIndex(int index)
{
    if (index >= 0 && index < m_items.count()) {
        m_snapAnimation->stop();
        setCurrentPosition(static_cast<double>(index));
        snapToTarget();
    }
}

QString StringWheelWidget::currentText() const
{
    int idx = currentIndex();
    if (idx >= 0 && idx < m_items.count()) {
        return m_items[idx];
    }
    return QString();
}

void StringWheelWidget::setOrientation(Qt::Orientation orientation)
{
    if (m_orientation != orientation) {
        m_orientation = orientation;
        recalcItemSize(); // 方向变了，依赖的长宽也变了，必须重算
        update();
    }
}

Qt::Orientation StringWheelWidget::orientation() const
{
    return m_orientation;
}

// --- 新增接口实现 ---
void StringWheelWidget::setVisibleItemCount(int count)
{
    if (count < 1) count = 1; // 至少显示1个
    m_visibleItemCount = count;
    recalcItemSize();
    update();
}

int StringWheelWidget::visibleItemCount() const
{
    return m_visibleItemCount;
}

void StringWheelWidget::recalcItemSize()
{
    int totalSize = (m_orientation == Qt::Vertical) ? height() : width();
    // 核心逻辑：总长 / 数量 = 单个大小
    m_itemSize = totalSize / m_visibleItemCount;
    if (m_itemSize < 1) m_itemSize = 1; // 防止除零或过小
}
// --------------------

double StringWheelWidget::currentPosition() const
{
    return m_currentPosition;
}

void StringWheelWidget::setCurrentPosition(double pos)
{
    if (m_items.isEmpty()) return;

    // 限制滚动范围，防止滚飞了
    double minPos = -0.5;
    double maxPos = m_items.count() - 0.5;

    if (pos < minPos) pos = minPos;
    if (pos > maxPos) pos = maxPos;

    if (!qFuzzyCompare(m_currentPosition, pos)) {
        m_currentPosition = pos;
        update();
    }
}

void StringWheelWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    int w = width();
    int h = height();
    int count = m_items.count();

    if (count == 0) return;

    // 背景色（可选，便于调试查看边界）
    // painter.fillRect(rect(), Qt::lightGray);

    int centerCoord = (m_orientation == Qt::Vertical) ? h / 2 : w / 2;

    // 绘制范围优化
    int drawRange = m_visibleItemCount / 2 + 2;

    int centerIndex = static_cast<int>(std::round(m_currentPosition));
    int start = std::max(0, centerIndex - drawRange);
    int end = std::min(count - 1, centerIndex + drawRange);

    // --- 字体大小核心修正 ---
    // 为了防止字体过大显示不全，我们强制设定基础字号为格子大小的 1/3
    // 例如：行高 60px -> 字号 20px。放大1.2倍后是 24px，远小于60px，绝对安全。
    int basePixelSize = m_itemSize / 3;
    if (basePixelSize < 8) basePixelSize = 8; // 最小限制

    QFont baseFont = font();
    baseFont.setPixelSize(basePixelSize);

    for (int i = start; i <= end; ++i) {
        double offset = i - m_currentPosition;
        int itemCenter = static_cast<int>(centerCoord + offset * m_itemSize);
        double dist = std::abs(offset * m_itemSize);

        // 视觉效果：距离计算
        double maxDist = (m_orientation == Qt::Vertical ? h : w) / 2.0;
        double scale = 1.0;
        double opacity = 1.0;

        if (dist < maxDist) {
            double ratio = 1.0 - (dist / maxDist);
            // 限制缩放：最大 1.15 倍，最小 0.8 倍
            scale = 0.8 + (ratio * 0.35);
            // 透明度：边缘更淡
            opacity = 0.3 + (ratio * 0.7);
        } else {
            scale = 0.8;
            opacity = 0.3;
        }

        painter.save();
        painter.setOpacity(opacity);

        // 应用缩放
        QFont f = baseFont;
        // 注意：这里使用 PointSizeF 或 PixelSize 乘 scale
        f.setPixelSize(static_cast<int>(basePixelSize * scale));

        if (std::abs(offset) < 0.3) {
            f.setBold(true); // 选中项加粗
        }
        painter.setFont(f);

        // 颜色：中间高亮，两边普通文本色
        if (std::abs(offset) < 0.5) {
            painter.setPen(palette().color(QPalette::Highlight));
        } else {
            painter.setPen(palette().color(QPalette::Text));
        }

        if (m_orientation == Qt::Vertical) {
            // 垂直模式：绘制区域居中
            QRect r(0, itemCenter - m_itemSize / 2, w, m_itemSize);
            painter.drawText(r, Qt::AlignCenter, m_items[i]);
        } else {
            // 水平模式
            QRect r(itemCenter - m_itemSize / 2, 0, m_itemSize, h);
            painter.drawText(r, Qt::AlignCenter, m_items[i]);
        }

        painter.restore();
    }
}

void StringWheelWidget::wheelEvent(QWheelEvent *event)
{
    m_snapAnimation->stop();

    QPoint numDegrees = event->angleDelta() / 8;
    double delta = 0.0;

    // 动态灵敏度：不需要除以太大的数，保证滚轮手感紧凑
    if (!numDegrees.isNull()) {
        if (m_orientation == Qt::Vertical) {
            delta = -numDegrees.y() / 15.0;
        } else {
            delta = -numDegrees.x() / 15.0;
            if (delta == 0) delta = -numDegrees.y() / 15.0;
        }
    }

    setCurrentPosition(m_currentPosition + delta);
    event->accept();
    snapToTarget();
}

void StringWheelWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_isDragging = true;
        m_snapAnimation->stop();
        m_lastMousePos = (m_orientation == Qt::Vertical) ? event->y() : event->x();
    }
    QWidget::mousePressEvent(event);
}

void StringWheelWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isDragging) {
        int currentPos = (m_orientation == Qt::Vertical) ? event->y() : event->x();
        int diff = m_lastMousePos - currentPos;

        // 核心拖拽逻辑：像素差 / 单项大小 = 索引变化量
        if (m_itemSize > 0) {
            double indexDiff = static_cast<double>(diff) / m_itemSize;
            setCurrentPosition(m_currentPosition + indexDiff);
        }
        m_lastMousePos = currentPos;
    }
    QWidget::mouseMoveEvent(event);
}

void StringWheelWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (m_isDragging) {
        m_isDragging = false;
        snapToTarget();
    }
    QWidget::mouseReleaseEvent(event);
}

void StringWheelWidget::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    // 窗口大小变了，必须重新计算单项大小，否则显示数量就不对了
    recalcItemSize();
}

void StringWheelWidget::snapToTarget()
{
    int targetIndex = static_cast<int>(std::round(m_currentPosition));

    if (targetIndex < 0) targetIndex = 0;
    if (targetIndex >= m_items.count()) targetIndex = m_items.count() - 1;

    if (qFuzzyCompare(m_currentPosition, static_cast<double>(targetIndex))) {
        return;
    }

    m_snapAnimation->setStartValue(m_currentPosition);
    m_snapAnimation->setEndValue(static_cast<double>(targetIndex));

    disconnect(m_snapAnimation, &QPropertyAnimation::finished, this, nullptr);
    connect(m_snapAnimation, &QPropertyAnimation::finished, this, [this, targetIndex](){
        emit currentIndexChanged(targetIndex);
        emit currentTextChanged(m_items[targetIndex]);
    });

    m_snapAnimation->start();
}
